package com.frinder.wx.web;

import com.frinder.wx.base.conf.MyTokenLoader;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.weixin4j.spi.IMessageHandler;
import org.weixin4j.util.TokenUtil;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

import static com.google.common.base.Strings.nullToEmpty;

/**
 * @ClassName WxController
 * @Description //TODO
 * @Author frinder
 * @Date 2018/12/5 18:37
 * @Version 1.0
 */
@Slf4j
@Controller
@RequestMapping("handler")
public class WxController {

    @Autowired
    private MyTokenLoader tokenLoader;

    @Autowired
    private IMessageHandler messageHandler;

    /**
     * @Author frinder
     * @Description 开发者接入验证
     * @Date 2018/12/5 18:38
     * @Param [request, response]
     * @Return void
     */
    @GetMapping
    public void get(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 消息来源可靠性验证
        // 微信加密签名
        String signature = nullToEmpty(request.getParameter("signature"));
        // 时间戳
        String timestamp = nullToEmpty(request.getParameter("timestamp"));
        // 随机数
        String nonce = nullToEmpty(request.getParameter("nonce"));
        // 获取 token
        String token = tokenLoader.get().getAccess_token();
        // 成为开发者验证
        String echoStr = nullToEmpty(request.getParameter("echostr"));
        // 确认此次GET请求来自微信服务器，原样返回 echostr 参数内容，则接入生效，成为开发者成功，否则接入失败
        if (TokenUtil.checkSignature(token, signature, timestamp, nonce)) {
            log.info("*** 开发者认证成功！");
            try (PrintWriter out = response.getWriter()) {
                out.write(echoStr);
            }
        } else {
            log.warn("*** 开发者认证失败！");
        }
    }

    /**
     * @Author frinder
     * @Description 接收微信消息
     * @Date 2018/12/5 18:38
     * @Param [request, response]
     * @Return void
     */
    @PostMapping
    public void post(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 微信加密签名
        String signature = nullToEmpty(request.getParameter("signature"));
        // 时间戳
        String timestamp = nullToEmpty(request.getParameter("timestamp"));
        // 随机数
        String nonce = nullToEmpty(request.getParameter("nonce"));
        //
        String token = tokenLoader.get().getAccess_token();
        // 设置编码格式
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/xml");
        try (PrintWriter out = response.getWriter()) {
            // 消息来源可靠性验证
            if (!TokenUtil.checkSignature(token, signature, timestamp, nonce)) {
                log.warn("*** 消息处理认证失败！");
                // 消息不可靠，直接返回
                out.write("");
            } else {
                try {
                    log.info("*** 消息处理认证成功！");
                    // 用户每次向公众号发送消息、或者产生自定义菜单点击事件时，响应URL将得到推送
                    ServletInputStream in = request.getInputStream();
                    String xml = messageHandler.invoke(in);
                    //返回结果
                    out.write(xml);
                } catch (Exception e) {
                    log.error("*** 系统异常，原因：{}", e.getMessage(), e);
                    out.write("");
                }
            }
        }
    }

}
